﻿using System.Runtime.InteropServices;

namespace Application.Service;

/// <summary>
/// 系统信息服务类
/// <para>功能：提供系统实时监控信息的Web API接口</para>
/// <list type="bullet">
/// <item><description>监控CPU、内存、网络、磁盘等系统资源</description></item>
/// <item><description>提供系统实时性能数据</description></item>
/// <item><description>封装系统监控功能为Web服务</description></item>
/// </list>
/// </summary>
[ApiDescriptionSettings(SplitCamelCase = false)]
[Route("api/system")]
public sealed class SystemService : ISystemService, IDynamicApiController, ITransient
{
    private readonly NetworkInterface[] networkInterfaces;
    private long previousTotalBytesSent;
    private long previousTotalBytesReceived;
    private DateTime previousTime;

    public SystemService()
    {
        networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
        previousTotalBytesSent = GetTotalBytesSent();
        previousTotalBytesReceived = GetTotalBytesReceived();
        previousTime = DateTime.Now;
    }

    /// <summary>
    /// 获取系统实时信息
    /// </summary>
    /// <returns>返回包含CPU、内存、网络、磁盘等信息的完整系统状态</returns>
    [HttpGet("info")]
    public SystemRealTimeInfo GetRealInfo()
    {
        var networkSpeed = GetNetworkSpeed();
        var diskInfo = GetDiskInfo();

        return new SystemRealTimeInfo
        {
            CpuUsage = GetCpuUsage(),
            MemoryUsage = GetMemoryUsage(),
            UploadSpeed = networkSpeed.uploadSpeed,
            DownloadSpeed = networkSpeed.downloadSpeed,
            DiskTotalSize = diskInfo.totalSize,
            DiskFreeSpace = diskInfo.freeSpace,
            DiskUsageRate = diskInfo.usageRate
        };
    }

    /// <summary>
    /// 监控系统CPU的实时使用情况
    /// </summary>
    /// <returns>返回当前CPU使用率的百分比值</returns>
    [HttpGet("cpu")]
    public float GetCpuUsage()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            // Windows平台使用PerformanceCounter
            using var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            return cpuCounter.NextValue();
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            // Linux平台通过读取/proc/stat文件计算CPU使用率
            return GetLinuxCpuUsage();
        }
        else
        {
            // 其他平台返回0
            return 0f;
        }
    }

    /// <summary>
    /// 监控系统内存的实时使用情况
    /// </summary>
    /// <returns>返回当前内存使用率的百分比值</returns>
    [HttpGet("memory")]
    public float GetMemoryUsage()
    {
        long totalMemory = GetTotalPhysicalMemory();
        long availableMemory = GetAvailableMemory();
        long usedMemory = totalMemory - availableMemory;
        return totalMemory > 0 ? (float)usedMemory / totalMemory * 100 : 0f;
    }

    /// <summary>
    /// 监控系统网络接口的实时传输速度
    /// </summary>
    /// <returns>返回当前网络上传和下载速度的实时元组数据，单位：字节/秒</returns>
    public (long uploadSpeed, long downloadSpeed) GetNetworkSpeed()
    {
        DateTime now = DateTime.Now;
        TimeSpan timeSpan = now - previousTime;
        long totalBytesSent = GetTotalBytesSent();
        long totalBytesReceived = GetTotalBytesReceived();

        long uploadSpeed = (long)((totalBytesSent - previousTotalBytesSent) / timeSpan.TotalSeconds);
        long downloadSpeed = (long)((totalBytesReceived - previousTotalBytesReceived) / timeSpan.TotalSeconds);

        previousTotalBytesSent = totalBytesSent;
        previousTotalBytesReceived = totalBytesReceived;
        previousTime = now;

        return (uploadSpeed, downloadSpeed);
    }

    /// <summary>
    /// 监控系统硬盘的存储空间使用情况
    /// </summary>
    /// <returns>包含硬盘总容量、剩余容量和使用率的元组，单位：字节</returns>
    [HttpGet("disk")]
    public (long totalSize, long freeSpace, float usageRate) GetDiskInfo()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            DriveInfo drive = new DriveInfo(Path.GetPathRoot(Environment.SystemDirectory));
            long totalSize = drive.TotalSize;
            long freeSpace = drive.TotalFreeSpace;
            float usageRate = totalSize > 0 ? (float)(totalSize - freeSpace) / totalSize * 100 : 0;

            return (totalSize, freeSpace, usageRate);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            // Linux平台通过df命令获取磁盘信息
            return GetLinuxDiskInfo();
        }
        else
        {
            return (0, 0, 0);
        }
    }

    /// <summary>
    /// Linux平台获取磁盘信息
    /// </summary>
    private (long totalSize, long freeSpace, float usageRate) GetLinuxDiskInfo()
    {
        try
        {
            // 执行df命令获取根分区信息
            var process = new System.Diagnostics.Process
            {
                StartInfo = new System.Diagnostics.ProcessStartInfo
                {
                    FileName = "df",
                    Arguments = "/",
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                }
            };

            process.Start();
            var output = process.StandardOutput.ReadToEnd();
            process.WaitForExit();

            // 解析df命令输出
            var lines = output.Split('\n');
            if (lines.Length >= 2)
            {
                var dataLine = lines[1]; // 第二行是根分区的数据
                var parts = dataLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                if (parts.Length >= 5)
                {
                    // 格式：文件系统 1K-块 已用 可用 已用% 挂载点
                    long totalSize = long.Parse(parts[1]) * 1024; // 转换为字节
                    long freeSpace = long.Parse(parts[3]) * 1024; // 转换为字节
                    float usageRate = float.Parse(parts[4].TrimEnd('%'));

                    return (totalSize, freeSpace, usageRate);
                }
            }
        }
        catch (Exception)
        {
            // 如果获取失败，返回默认值
        }

        return (0, 0, 0);
    }

    private long GetTotalBytesSent()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            long total = 0;
            foreach (var nic in networkInterfaces)
            {
                if (nic.OperationalStatus == OperationalStatus.Up)
                {
                    total += nic.GetIPv4Statistics().BytesSent;
                }
            }
            return total;
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            // Linux平台通过读取/proc/net/dev文件获取网络统计
            return GetLinuxNetworkBytesSent();
        }
        else
        {
            return 0;
        }
    }

    private long GetTotalBytesReceived()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            long total = 0;
            foreach (var nic in networkInterfaces)
            {
                if (nic.OperationalStatus == OperationalStatus.Up)
                {
                    total += nic.GetIPv4Statistics().BytesReceived;
                }
            }
            return total;
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            // Linux平台通过读取/proc/net/dev文件获取网络统计
            return GetLinuxNetworkBytesReceived();
        }
        else
        {
            return 0;
        }
    }

    /// <summary>
    /// Linux平台获取网络发送字节数
    /// </summary>
    private long GetLinuxNetworkBytesSent()
    {
        try
        {
            var netDevLines = File.ReadAllLines("/proc/net/dev");
            long totalSent = 0;

            foreach (var line in netDevLines.Skip(2)) // 跳过前两行标题
            {
                var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length >= 10)
                {
                    // 格式：接口名 | 接收字节 | 接收包 | ... | 发送字节 | 发送包 | ...
                    totalSent += long.Parse(parts[9]); // 发送字节在第9个字段
                }
            }
            return totalSent;
        }
        catch (Exception)
        {
            return 0;
        }
    }

    /// <summary>
    /// Linux平台获取网络接收字节数
    /// </summary>
    private long GetLinuxNetworkBytesReceived()
    {
        try
        {
            var netDevLines = File.ReadAllLines("/proc/net/dev");
            long totalReceived = 0;

            foreach (var line in netDevLines.Skip(2)) // 跳过前两行标题
            {
                var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length >= 10)
                {
                    // 格式：接口名 | 接收字节 | 接收包 | ... | 发送字节 | 发送包 | ...
                    totalReceived += long.Parse(parts[1]); // 接收字节在第1个字段
                }
            }
            return totalReceived;
        }
        catch (Exception)
        {
            return 0;
        }
    }

    /// <summary>
    /// Linux平台获取CPU使用率
    /// </summary>
    private float GetLinuxCpuUsage()
    {
        try
        {
            // 读取/proc/stat文件获取CPU信息
            var statLines = File.ReadAllLines("/proc/stat");
            var cpuLine = statLines.FirstOrDefault(line => line.StartsWith("cpu "));

            if (cpuLine != null)
            {
                var parts = cpuLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length >= 8)
                {
                    // 解析CPU时间：user, nice, system, idle, iowait, irq, softirq, steal
                    long user = long.Parse(parts[1]);
                    long nice = long.Parse(parts[2]);
                    long system = long.Parse(parts[3]);
                    long idle = long.Parse(parts[4]);
                    long iowait = long.Parse(parts[5]);
                    long irq = long.Parse(parts[6]);
                    long softirq = long.Parse(parts[7]);
                    long steal = parts.Length > 8 ? long.Parse(parts[8]) : 0;

                    long totalCpuTime = user + nice + system + idle + iowait + irq + softirq + steal;
                    long idleTime = idle + iowait;

                    // 计算使用率
                    if (totalCpuTime > 0)
                    {
                        return (float)(totalCpuTime - idleTime) / totalCpuTime * 100;
                    }
                }
            }
        }
        catch (Exception)
        {
            // 如果读取失败，返回0
        }

        return 0f;
    }

    /// <summary>
    /// 获取可用内存
    /// </summary>
    private long GetAvailableMemory()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            // Windows平台使用PerformanceCounter
            using var ramCounter = new PerformanceCounter("Memory", "Available MBytes");
            return (long)(ramCounter.NextValue() * 1024 * 1024);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            // Linux平台通过读取/proc/meminfo文件获取内存信息
            return GetLinuxAvailableMemory();
        }
        else
        {
            return 0;
        }
    }

    /// <summary>
    /// Linux平台获取可用内存
    /// </summary>
    private long GetLinuxAvailableMemory()
    {
        try
        {
            var memInfoLines = File.ReadAllLines("/proc/meminfo");
            long memAvailable = 0;
            long memFree = 0;
            long buffers = 0;
            long cached = 0;

            foreach (var line in memInfoLines)
            {
                if (line.StartsWith("MemAvailable:"))
                {
                    memAvailable = ParseMemInfoLine(line);
                }
                else if (line.StartsWith("MemFree:"))
                {
                    memFree = ParseMemInfoLine(line);
                }
                else if (line.StartsWith("Buffers:"))
                {
                    buffers = ParseMemInfoLine(line);
                }
                else if (line.StartsWith("Cached:"))
                {
                    cached = ParseMemInfoLine(line);
                }
            }

            // 优先使用MemAvailable，如果没有则计算
            if (memAvailable > 0)
            {
                return memAvailable * 1024; // 转换为字节
            }
            else
            {
                // 计算可用内存：MemFree + Buffers + Cached
                return (memFree + buffers + cached) * 1024; // 转换为字节
            }
        }
        catch (Exception)
        {
            return 0;
        }
    }

    /// <summary>
    /// 解析/proc/meminfo文件行
    /// </summary>
    private long ParseMemInfoLine(string line)
    {
        var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (parts.Length >= 2)
        {
            return long.Parse(parts[1]);
        }
        return 0;
    }

    /// <summary>
    /// 获取总物理内存
    /// </summary>
    private long GetTotalPhysicalMemory()
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            // Windows平台使用WMI
            using (var searcher = new ManagementObjectSearcher("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    return Convert.ToInt64(obj["TotalPhysicalMemory"]);
                }
            }
            return 0;
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            // Linux平台通过读取/proc/meminfo文件获取总内存
            return GetLinuxTotalMemory();
        }
        else
        {
            return 0;
        }
    }

    /// <summary>
    /// Linux平台获取总内存
    /// </summary>
    private long GetLinuxTotalMemory()
    {
        try
        {
            var memInfoLines = File.ReadAllLines("/proc/meminfo");
            foreach (var line in memInfoLines)
            {
                if (line.StartsWith("MemTotal:"))
                {
                    return ParseMemInfoLine(line) * 1024; // 转换为字节
                }
            }
        }
        catch (Exception)
        {
            // 如果读取失败，返回0
        }
        return 0;
    }
}




    
public class SystemRealTimeInfo
{
    /// <summary>
    /// CPU使用率百分比
    /// </summary>
    public float CpuUsage { get; set; }

    /// <summary>
    /// 内存使用率百分比
    /// </summary>
    public float MemoryUsage { get; set; }

    /// <summary>
    /// 上传速度，单位：字节/秒
    /// </summary>
    public long UploadSpeed { get; set; }

    /// <summary>
    /// 下载速度，单位：字节/秒
    /// </summary>
    public long DownloadSpeed { get; set; }

    /// <summary>
    /// 硬盘总大小，单位：字节
    /// </summary>
    public long DiskTotalSize { get; set; }

    /// <summary>
    /// 硬盘剩余容量，单位：字节
    /// </summary>
    public long DiskFreeSpace { get; set; }

    /// <summary>
    /// 硬盘使用率百分比
    /// </summary>
    public float DiskUsageRate { get; set; }
}
